package com.example.config;

import lombok.ToString;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.*;

/**
 * 由于@Configuration有着比较多的概念需要讲清楚，所以单独抽取出此类来讲解部分概念好阅读些。<p>
 * {@code @Configuration}：表示当前类为Spring容器配置类，等价于于当前项目中的application.xml。
 * 表示该类声明了一个或多个@Bean方法，并且可以被 Spring 容器处理以在运行时为这些 bean 生成 bean 定义和服务请求。@Configuration使用@Component进行元注释，
 * 因此@Configuration类是组件扫描的候选对象，因此也可以像任何常规的@Component一样使用@Autowired / @Inject。特别是，如果存在单个构造函数，则将隐式地应用自动装配语义<p>
 *
 * @author yexi
 * @see org.springframework.context.annotation.ConfigurationClassUtils#isFullConfigurationClass(BeanDefinition beanDef)
 * @see ConfigurationClassPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
 */
@Configuration
@ToString(callSuper = true)
public class AppConfig {

    private CommonBean cb;

    /**
     * 由于存在单个构造函数，则会隐式应用自动装配语义(被spring进行动态代理)，从spring容器中通过getBean找寻一个相同类型或者相同名称的bean，如果不存在，则启动就会报错。
     * 1、单个构造函数，所以不可重载构造方法。否则该理论失效(多参重载甚至会直接报错)。
     */
    public AppConfig(CommonBean cb) {
        this.cb = cb;
        System.out.println("AppConfig的bean对象被创建了: " + this);
    }

}
